package com.iretailer.report.influxdb.service;

import com.iretailer.report.dto.DwellTimeModel;
import com.iretailer.report.influxdb.dao.InfluxdbDao;
import com.iretailer.report.influxdb.model.DwellTime;
import com.iretailer.report.influxdb.model.DwellTimePZ;
import com.iretailer.report.influxdb.model.PassByFlow;
import com.iretailer.report.influxdb.util.TableName;
import com.iretailer.report.model.PhysicalZoneMall;
import com.iretailer.report.util.TimeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Auther: xjw
 * @Date: 2019/1/28 13:52
 * @Description:
 */
@Service
public class InfluxdbDwellService {

    @Autowired
    private InfluxdbDao influxdbDao;

    /**
     * @Author xjw
     * @Date 2019/1/28 13:54
     * @Description :  插入 dwell 数据
     **/
    public int insertDwellTime(List<DwellTime> post, TableName.Dwell table) {
        int result = -1;
        int separateNumber = 50000;
        int size = post.size();
        if (size <= separateNumber) {
            result = influxdbDao.batchInsertDwelltime(post, table);
        } else {
            int batchSize = size / separateNumber;
            int remain = size % separateNumber;
            for (int i = 0; i < batchSize; ) {
                int index = i * separateNumber;
                int toIndex = index + separateNumber;
                result += influxdbDao.batchInsertDwelltime(post.subList(index, toIndex), table);
            }
            if (remain > 0) {
                result += influxdbDao.batchInsertDwelltime(post.subList(size - remain, size), table);
            }

        }
        return result;
    }

    /***
     *  向  dwelltime_physicalzone 插入数据
     * @param post
     * @return
     */
    public int insertDwellTimePZ(List<DwellTimePZ> post) {
        int result = -1;
        int separateNumber = 50000;
        int size = post.size();
        if (size <= separateNumber) {
            result = influxdbDao.batchInsertDwelltimePZ(post);
        } else {
            int batchSize = size / separateNumber;
            int remain = size % separateNumber;
            for (int i = 0; i < batchSize; ) {
                int index = i * separateNumber;
                int toIndex = index + separateNumber;
                result += influxdbDao.batchInsertDwelltimePZ(post.subList(index, toIndex));
            }
            if (remain > 0) {
                result += influxdbDao.batchInsertDwelltimePZ(post.subList(size - remain, size));
            }

        }
        return result;
    }

    public List<DwellTime> selectDwell(String timezone, String type, List<Long> zoneIds, String startTime, String endTime, String period) {
        switch (type) {
            case "All":
                switch (period) {
                    case "1m":
                        return influxdbDao.selectDwellTimeGrid(timezone, TableName.Dwell.DwellTime, zoneIds, startTime, endTime);
                    default:
                        return influxdbDao.selectDwellGroupByZoneId(false, timezone, TableName.Dwell.DwellTime, zoneIds, startTime, endTime, period);
                }
            default:
                switch (period) {
                    case "1m":
                        return influxdbDao.selectDwellTimeGrid(timezone, TableName.Dwell.DwellTime_B, zoneIds, startTime, endTime);
                    default:
                        return influxdbDao.selectDwellGroupByZoneId(false, timezone, TableName.Dwell.DwellTime_B, zoneIds, startTime, endTime, period);
                }
        }
    }

    public List<DwellTime> selectDwellGrid(String timezone, TableName.Dwell table, List<Long> zoneIds, String sartTime, String endTime) {
        return influxdbDao.selectDwellTimeGrid(timezone, table, zoneIds, sartTime, endTime);
    }

    public List<DwellTime> selectDwellGroupByTime(String timeZone, TableName.Dwell table, List<Long> zoneIds, String startTime, String endTime, String period) {
        return influxdbDao.selectDwellGroupByTime(timeZone, table, zoneIds, startTime, endTime, period);
    }

    public List<DwellTime> getZero(String timeZone, TableName.Dwell table, List<Long> zoneIds, String startTime, String endTime) {
        List<DwellTime> oldDwellTime = influxdbDao.selectDwellTimeGrid(timeZone, table, zoneIds, startTime, endTime);
        oldDwellTime.forEach(it -> {
            it.setNumberServed(0);
            it.setSecondsOccupied(0);
        });
        return oldDwellTime;
    }

    public List<DwellTimePZ> getDwellTimePZZero(String timeZone, List<Long> zoneIds, String startTime, String endTime) {
        List<DwellTimePZ> oldDwellTime = influxdbDao.selectDwellTimePZGrid(timeZone, zoneIds, startTime, endTime);
        oldDwellTime.forEach(it -> {
            it.setEntranceCount(0);
            it.setPassCount(0);
            it.setSecondsCount(0);
            it.setStayCount(0);
        });
        return oldDwellTime;
    }

    public List<DwellTimePZ> selectDwellTimePZGroupByZoneId(String timezone, TableName.Dwell table, List<Long> zoneIds, String sartTime, String endTime, String period) {
        return influxdbDao.selectDwellTimePZGroupByZoneId(timezone, table, zoneIds, sartTime, endTime, period);
    }

    public List<DwellTimeModel> getPhysicalZones_PeriodPassByFlow(List<PhysicalZoneMall> physicalZones, String startTime, String endTime, String period) {
        List<DwellTimeModel> result = new ArrayList<>();
        if (physicalZones != null && physicalZones.size() > 0) {
            Map<String, List<PhysicalZoneMall>> timezonePZMap = physicalZones.stream().collect(Collectors.groupingBy(PhysicalZoneMall::getTimeZone));
            timezonePZMap.entrySet().forEach(it -> {
                String timezone = it.getKey();
                Map<Long, PhysicalZoneMall> pzmap = it.getValue().stream().collect(Collectors.toMap(PhysicalZoneMall::getId, a -> a));
                List<DwellTimePZ> dwellTimePZList = selectDwellTimePZGroupByZoneId(timezone, TableName.Dwell.DwellTime_PZ, new ArrayList<>(pzmap.keySet()), startTime, endTime, period);
                if (dwellTimePZList != null && dwellTimePZList.size() > 0) {
                    for (DwellTimePZ dpz : dwellTimePZList) {
                        PhysicalZoneMall pzm = pzmap.get(Long.valueOf(dpz.getZoneid()));
                        DwellTimeModel model = new DwellTimeModel();
                        model.setPhysicalZoneId(pzm.getId());
                        model.setPhysicalZoneName(pzm.getName());
                        model.setMallId(pzm.getMallId());
                        model.setMallName(pzm.getMallName());
                        model.setCityId(pzm.getCityId());
                        model.setZonedDateTime(dpz.getTime());
                        String time = TimeUtil.zoneDateTime_format(dpz.getTime());
                        model.setDateTime(time);
                        model.setEntranceCount(dpz.getEntranceCount());
                        model.setPassCount(dpz.getPassCount());
                        model.setStayCount(dpz.getStayCount());
                        model.setSecondsCount(dpz.getSecondsCount());
                        result.add(model);
                    }
                }
            });
        }
        return result;
    }

}
